#ifndef THREAD_POOL_HPP
#define THREAD_POOL_HPP

#include <vector>
#include <queue>
#include <functional>
#include <pthread.h>
#include <unistd.h> // for usleep
#include <iostream>

// 线程池任务类型定义，使用 std::function 以便接受任何可调用对象
// Task type definition for the thread pool, using std::function to accept any callable object
using Task = std::function<void()>;

class ThreadPool {
public:
    // 构造函数：创建指定数量的线程
    // Constructor: creates a specified number of threads
    ThreadPool(size_t num_threads) : stop(false) {
        pthread_mutex_init(&queue_mutex, nullptr);
        pthread_cond_init(&condition, nullptr);

        for (size_t i = 0; i < num_threads; ++i) {
            pthread_t tid;
            pthread_create(&tid, nullptr, &ThreadPool::worker_thread, this);
            threads.push_back(tid);
        }
    }

    // 析构函数：等待所有任务完成并销毁线程池
    // Destructor: waits for all tasks to complete and destroys the thread pool
    ~ThreadPool() {
        // 加锁以安全地修改 stop 标志
        // Lock to safely modify the stop flag
        pthread_mutex_lock(&queue_mutex);
        stop = true;
        pthread_mutex_unlock(&queue_mutex);

        // 唤醒所有等待的线程，以便它们可以检查 stop 标志并退出
        // Wake up all waiting threads so they can check the stop flag and exit
        pthread_cond_broadcast(&condition);

        // 等待所有线程结束
        // Wait for all threads to finish
        for (pthread_t& thread : threads) {
            pthread_join(thread, nullptr);
        }

        // 销毁互斥锁和条件变量
        // Destroy the mutex and condition variable
        pthread_mutex_destroy(&queue_mutex);
        pthread_cond_destroy(&condition);
    }

    // 向任务队列中添加一个新任务
    // Enqueue a new task to the task queue
    void enqueue(Task task) {
        pthread_mutex_lock(&queue_mutex);
        tasks.push(std::move(task));
        pthread_mutex_unlock(&queue_mutex);

        // 通知一个等待的线程有新任务了
        // Notify a waiting thread that a new task is available
        pthread_cond_signal(&condition);
    }

private:
    // 工作线程函数 (必须是静态的)
    // Worker thread function (must be static)
    static void* worker_thread(void* arg) {
        ThreadPool* pool = static_cast<ThreadPool*>(arg);
        pool->run();
        return nullptr;
    }

    // 每个工作线程的主循环
    // Main loop for each worker thread
    void run() {
        while (true) {
            Task task;
            
            // 临界区：从队列中取任务
            // Critical section: get a task from the queue
            pthread_mutex_lock(&queue_mutex);

            // 当队列为空且线程池没有停止时，等待条件变量
            // When the queue is empty and the pool is not stopped, wait on the condition variable
            while (!stop && tasks.empty()) {
                pthread_cond_wait(&condition, &queue_mutex);
            }

            // 如果线程池已停止且任务队列为空，则线程退出
            // If the pool is stopped and the queue is empty, the thread exits
            if (stop && tasks.empty()) {
                pthread_mutex_unlock(&queue_mutex);
                return;
            }

            // 取出一个任务
            // Get a task
            task = std::move(tasks.front());
            tasks.pop();
            
            pthread_mutex_unlock(&queue_mutex);

            // 执行任务
            // Execute the task
            task();
        }
    }

    std::vector<pthread_t> threads;     // 工作线程集合 (Collection of worker threads)
    std::queue<Task> tasks;             // 任务队列 (Task queue)
    pthread_mutex_t queue_mutex;        // 队列互斥锁 (Queue mutex)
    pthread_cond_t condition;           // 条件变量，用于线程同步 (Condition variable for thread synchronization)
    bool stop;                          // 停止标志 (Stop flag)
};

#endif // THREAD_POOL_HPP
